package com.novunda.platform.common.handler;

import com.novunda.platform.common.domain.LogCount;
import com.novunda.platform.common.handler.CommonHandler;
import com.novunda.platform.common.handler.LogCallBack;
import com.novunda.platform.common.utils.CacheUtils;
import com.novunda.platform.common.utils.UserUtils;
import com.novunda.platform.entities.Log;
import com.novunda.platform.entities.Statistics;
import com.novunda.platform.entities.User;
import com.novunda.platform.services.LogService;
import com.novunda.platform.services.StatisticsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.Date;

/**
 * 日志处理
 *
 * @author yangg
 * @since 2016/9/18.
 */
@Service("handler")
public class LogHandlerImpl implements CommonHandler {

    @Autowired
    private LogService logService;
    @Autowired
    private StatisticsService statisticsService;
    @Autowired
    private Environment env;

    /**
     * 缓存名称
     */
    private static final String LOG_COUNT_KEY = "log_count";

    @Override
    public Object doHandler(LogCallBack callBack) {

        if (UserUtils.getUser() == null || UserUtils.getUser().getId() == null) {
            return callBack.doHandler();
        }
        if (!callBack.forceLog() && !beforeLog()) {
            //不强制记录
            //不需要记录则直接执行业务
            return callBack.doHandler();
        }
        Log log = callBack.generate();//获取生成的日志

        Object object = null;
        try {
            //封装固定参数
            User user = UserUtils.getUser();
            log.setSystem(env.getProperty("log.system", ""));
            log.setIp(user.getLoginIp());

            log.setUserName(user.getRealName());
            log.setLoginName(user.getLoginName());
            log.setOrgName(user.getCompany().getName());
            log.setUpdateDate(new Date());
            log.setCreateDate(new Date());
            //执行业务操作
            object = callBack.doHandler();
            //封装业务结果
            log.setResult("成功");
        } catch (Exception e) {
            //错误日志记录
            log.setResult("失败");
            throw e;
        } finally {
            logService.save(log);
            LogCount logCount = (LogCount) CacheUtils.getObject(LOG_COUNT_KEY);
            if (logCount == null) {
                logCount = new LogCount(logService.count());
            }
            logCount.setCountNum(logCount.getCountNum() + 1);
            CacheUtils.putObject(LOG_COUNT_KEY, logCount);
        }
        //返回业务执行结果
        return object;
    }

    /**
     * 是否需要记录
     *
     * @return 是否需要记录
     */
    private boolean beforeLog() {

        Statistics statistics = statisticsService.getStatistics();
        // 设置为不记录则不记录

        if (statistics.getRecordStatus() != 0) {
            return false;
        }

        if (CacheUtils.getObject(LOG_COUNT_KEY) == null) {
            CacheUtils.putObject(LOG_COUNT_KEY, new LogCount(logService.count()));
        }
        LogCount logCount = (LogCount) CacheUtils.getObject(LOG_COUNT_KEY);
        //当前时间
        long lastTime = logCount.getLastTime();
        if (new Date().getTime() - lastTime >= Long.valueOf(env.getProperty("log.count.expire"))) {
            //缓存过期 更新缓存
            CacheUtils.putObject(LOG_COUNT_KEY, new LogCount(logService.count()));
        }

        //已有记录超过最大纪录 则 不记录
        return logCount.getCountNum() < statistics.getRecordNumber();
    }
}
